package com.zy.rpc.consumer.config;

import com.zy.rpc.common.balance.LoadBalance;
import com.zy.rpc.common.balance.impl.FullRoundBalance;
import com.zy.rpc.common.balance.impl.RandomBalance;
import com.zy.rpc.common.discovery.DiscoveryService;
import com.zy.rpc.common.discovery.impl.ZookeeperDiscoveryService;
import com.zy.rpc.consumer.processor.RpcClientProcessor;
import com.zy.rpc.consumer.proxy.ClientStubProxyFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;


/**
 * @author zy
 * @date 2023/5/7 10:39
 */


@Configuration
public class RpcClientAutoConfiguration {

    @Bean
    public RpcClientProperties rpcClientProperties(Environment environment){
        BindResult<RpcClientProperties> result= Binder.get(environment).bind("rpc.client",RpcClientProperties.class);
        return result.get();
    }

    @Bean
    @ConditionalOnMissingBean
    public ClientStubProxyFactory clientStubProxyFactory(){
        return new ClientStubProxyFactory();
    }


    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(RpcClientProperties.class)
    public DiscoveryService discoveryService(
            @Autowired RpcClientProperties rpcClientProperties
    ){
        return  new ZookeeperDiscoveryService(rpcClientProperties.getDiscoveryAddr());
    }


    @Bean
    @DependsOn({"discoveryService", "rpcClientProperties"})
    public RpcClientProcessor rpcClientProcessor() {
        return new RpcClientProcessor();
    }

}
